#include <stdio.h>
#include <windows.h>

#include "config.h"
#include "event.h"
#include "util.h"
#include "serial.h"
#include "progress.h"

#define CRC_SIZE 2

int
main(int argc, char **argv)
{
	char *com_file;
	char *out_file;
	char *conf_file;
	FILE *fpconf;
	FILE *fpout;
	struct serial_dev sdev;
	int r, total;
	char buf[128];
	struct config config;
	uint32_t read_addr;
	uint32_t amt;

	if (argc != 4) {
		fprintf(stderr, "usage: %s comN config_file "
		    "output_file\n", argv[0]);
		exit(1);
	}

	com_file = argv[1];
	conf_file = argv[2];
	out_file = argv[3];

	fpout = fopen(out_file, "wb+");
	if (fpout == NULL) {
		fprintf(stderr, "error: could not open %s\n", out_file);
		exit(1);
	}
	fpconf = fopen(conf_file, "rb");
	if (fpconf == NULL) {
		fprintf(stderr, "error: could not open %s\n",
		    conf_file);
		exit(1);
	}

	r = fread(&config, 1, sizeof(config), fpconf);
	
	if (!valid_config(&config)) {
		fprintf(stderr, "error: invalid config read.\n");
		exit(1);
	}
	
	if (init_serial(&sdev, com_file) == -1)
		exit(1);

	strcpy(buf, "!!!\recho off\r");
	r = write_ser(&sdev, buf, strlen(buf));
	if (r != strlen(buf)) {
		fprintf(stderr, "error: could not write.\n");
		exit(1);
	}

	ser_flush(&sdev);

	if (config.nvm_start_addr == 0) {
		fprintf(stderr, "error: nothing logged.\n");
		exit(1);
	}

	read_addr = 0;
	while (read_addr < config.nvm_start_addr) {
		amt = config.nvm_start_addr - read_addr;
		if (amt > 126)
			amt = 126;
	
		snprintf(buf, sizeof(buf), "read_log %08x %d\r",
		    read_addr, amt);

#if 0
		printf("%s\n", buf);
#endif

		r = write_ser(&sdev, buf, strlen(buf));
		if (r != strlen(buf)) {
			fprintf(stderr, "error: could send command.\n");
			exit(1);
		}

		total = 0;
		do {
			r = read_ser(&sdev, buf + total,
			    amt + CRC_SIZE - total);
			if (r == 0) {
				fprintf(stderr, "error: read "
				    "timeout.\n");
				exit(1);
			}
			total += r;

		} while (total < amt + CRC_SIZE);

		if (!valid_crc(buf, amt + CRC_SIZE)) {
			fprintf(stderr, "error: invalid CRC at "
			    "%08x.\n", read_addr);
			exit(1);
		}

		r = fwrite(buf, 1, amt, fpout);
		if (r != amt) {
			fprintf(stderr, "error: could not write to "
			    "local file.\n");
			exit(1);
		}

		read_addr += amt;
		
		progress_bar(read_addr, config.nvm_start_addr);
	}

	close_serial(&sdev);

	fclose(fpconf);
	fclose(fpout);

	return 0;
}
